import bottleConf from '../../confs/bottle-conf'
import blockConf from '../../confs/block-conf'
import { customAnimation } from '../../libs/animation'


class Bottle {
    constructor () {
        this.direction = 0
        this.axis = null
        this.status = 'stop'
        this.scale = 1
    }

    init () {
        this.loader = new THREE.TextureLoader()
        this.obj = new THREE.Object3D()
        this.obj.name = 'bottle'
        this.obj.position.set(bottleConf.initPosition.x, bottleConf.initPosition.y + 30, bottleConf.initPosition.z)
        
        const { specularMaterial, bottomMaterial, middleMaterial } = this.loadTexture()

        this.bottle = new THREE.Object3D()
        
        this.human = new THREE.Object3D()


        var headRadius = bottleConf.headRadius

        this.head = new THREE.Mesh(
            new THREE.OctahedronGeometry(headRadius),
            bottomMaterial
        )
        this.head.castShadow = true

        var bottom = new THREE.Mesh(
            new THREE.CylinderGeometry(
                0.62857 * headRadius, 
                0.907143 * headRadius,
                1.91423 * headRadius,
                20
            ),
            bottomMaterial
        )
        bottom.castShadow = true

        var middle = new THREE.Mesh(
            new THREE.CylinderGeometry(
                headRadius / 1.4,
                headRadius / 1.44 * 0.88,
                headRadius * 1.2,
                20
            ),
            middleMaterial
        )
        middle.castShadow = true
        middle.position.y = 1.3857 * headRadius
        middle.position.x = 0
        middle.position.z = 0


        var topGeomentry = new THREE.SphereGeometry(headRadius / 1.4, 20, 20)
        topGeomentry.scale(1, 0.54, 1)
        var top = new THREE.Mesh(
            topGeomentry,
            specularMaterial
        )
        top.castShadow = true
        top.position.y = 1.8143 * headRadius
        top.position.x = 0
        top.position.z = 0
        

        this.head.position.y = 3.57143 * headRadius
        this.head.position.x = 0
        this.head.position.z = 0

        this.body = new THREE.Object3D()
        this.body.add(bottom)
        this.body.add(middle)
        this.body.add(top)

        this.human.add(this.head)
        this.human.add(this.body)
        
        this.bottle.add(this.human)

        this.bottle.position.y = 2.3
        this.bottle.position.x = 0
        this.bottle.position.z = 0
        this.obj.add(this.bottle)
    }

    loadTexture () {
        var specularTexture = this.loader.load('/game/res/images/head.png')
        var specularMaterial = new THREE.MeshBasicMaterial({
            map: specularTexture
        })
        var bottomTexture = this.loader.load('/game/res/images/bottom.png') 
        var bottomMaterial = new THREE.MeshBasicMaterial({
            map: bottomTexture
        })
        var middleTexture = this.loader.load('/game/res/images/middle.png') 
        var middleMaterial = new THREE.MeshBasicMaterial({
            map: middleTexture
        })
        return {
            specularMaterial,
            bottomMaterial,
            middleMaterial
        }
    }

    _shrink () {
        const MIN_SCALE = 0.55
        const HORIZON_DELTA_SCALE = 0.007
        const DELTA_SCALE = 0.005
        const HEAD_DELTA = 0.03

        this.scale -= DELTA_SCALE
        this.scale = Math.max(MIN_SCALE, this.scale)
        if (this.scale <= MIN_SCALE) {
            return
        }
        this.body.scale.y = this.scale
        this.body.scale.x += HORIZON_DELTA_SCALE
        this.body.scale.z += HORIZON_DELTA_SCALE
        this.head.position.y -= HEAD_DELTA

        const bottleDeltaY = HEAD_DELTA / 2
        const deltaY = blockConf.heigth * DELTA_SCALE / 2
        this.obj.position.y -= bottleDeltaY + deltaY * 2
    }

    update () {
        if (this.status === 'shrink') {
            this._shrink()
        }
        this.head.rotation.y += 0.06
    }

    showup () {
        customAnimation.to(1.0, this.obj.position, {
            x: bottleConf.initPosition.x, 
            y: bottleConf.initPosition.y + blockConf.heigth / 2, 
            z: bottleConf.initPosition.z
        }, 'BounceEaseOut')
    }

    setDiection (direction, axis) {
        this.direction = direction
        this.axis = axis
    }

    shrink () {
        this.status = 'shrink'
    }

    stop () {
        this.scale = 1
        this.status = 'stop'
    }

    rotate () {
        const scale = 1.4
        this.human.rotation.x = this.human.rotation.z = 0
        if (this.direction == 0) { // x
            // customAnimation.to(0.14, this.human.rotation, { z: this.human.rotation.z - Math.PI }, 'Linear', 0)
            // customAnimation.to(0.18, this.human.rotation, { z: this.human.rotation.z - 2 * Math.PI }, 'Linear', 0)
            customAnimation.to(0.1, this.head.position, { y: this.head.position.y + 0.9 * scale, x: this.head.position.x + 0.45 * scale }, 'Linear', 0.1)
            customAnimation.to(0.1, this.head.position, { y: this.head.position.y - 0.9 * scale, x: this.head.position.x - 0.45 * scale }, 'Linear', 0.1)
            customAnimation.to(0.15, this.head.position, { y: 7.56, x: 0 }, 'Linear', 0.25)
            customAnimation.to(0.1, this.body.scale, { y: Math.max(scale, 1), x: Math.max(Math.min(1 / scale, 1), 0.7), z: Math.max(Math.min(1 / scale, 1), 0.7) }, 'Linear', 0.1)
            customAnimation.to(0.1, this.body.scale, { y: Math.min(0.9 / scale, 0.7), x: Math.max(scale, 1.2), z: Math.max(scale, 1.2) }, 'Linear', 0.1)
            customAnimation.to(0.3, this.body.scale, { y: 1, x: 1, z: 1 }, 'Linear', 0.2)
          } else if (this.direction == 1) { // z
            // customAnimation.to(0.14, this.human.rotation, { x: this.human.rotation.x - Math.PI }, 'Linear', 0.1)
            // customAnimation.to(0.18, this.human.rotation, { x: this.human.rotation.x - 2 * Math.PI }, 'Linear', 0.14)
            // customAnimation.to(0.1, this.head.position, { y: this.head.position.y + 0.9 * scale, z: this.head.position.z - 0.45 * scale }, 'Linear', 0.1)
            // customAnimation.to(0.1, this.head.position, { z: this.head.position.z + 0.45 * scale, y: this.head.position.y - 0.9 * scale }, 'Linear', 0.1)
            // customAnimation.to(0.15, this.head.position, { y: 7.56, z: 0 }, 'Linear', 0.25)
            // customAnimation.to(0.05, this.body.scale, { y: Math.max(scale, 1), x: Math.max(Math.min(1 / scale, 1), 0.7), z: Math.max(Math.min(1 / scale, 1), 0.7) }, 'Linear')
            // customAnimation.to(0.05, this.body.scale, { y: Math.min(0.9 / scale, 0.7), x: Math.max(scale, 1.2), z: Math.max(scale, 1.2) }, 'Linear', 0.1)
            // customAnimation.to(0.2, this.body.scale, { y: 1, x: 1, z: 1 }, 'Linear', 0.2)
          }
    }
}

export default new Bottle()